﻿//===============================================================================
//	LoginServer.cpp
//===============================================================================
#ifdef _MSC_VER
#ifdef USE_VLD_CHECK_LEAK
#include "vld.h"
#endif
#endif

#include "LoginServer.h"

#include <thread>
#include <chrono>

#include "../../3rd/libjson/json.h"

#include "../share/common_define.h"
#include "../share/GameHostManager.h"
#include "../share/proxyclient_service.h"
#include "../share/client_msg.h"
#include "login_logic.h"
#include "../share/tplmgr.h"
#include "../share/dirtyword.h"
#include "loginobj_manager.h"
#include "../share/log.h"
#include "../share/net_msg_transfer.h"
#include "login_queue_mgr.h"


#ifdef _MSC_VER
char * g_dump_exe_name = "LoginServer";
#endif



LoginServer::LoginServer():
	server_net(this, get_service_pump())
{
	max_client_count_ = 10240;
}

LoginServer::~LoginServer()
{

}

int32_t LoginServer::Initialize(void)
{
	int32_t listen_port = GameHostManager::GetInstance().GetLoginHostListenPort();
//	server_net.OnInit(listen_port);
	CProxyClientService::GetInstance().InitializeServer(GetServiceType(), GetServiceID(), this);
	CProxyClientService::GetInstance().Initialize(1024 * 100, 1024 * 100);

	login_server_.Initialize(1024 * 100, 1024 * 100);
	int32_t rtn = login_server_.Startup(listen_port);
	if (rtn != ::common::SUCCEED)
	{
		return rtn;
	}
	LOG_INFO("default", "login server startup success, port %d", listen_port);

	CLoginLogic::GetInstance().Initialize();
	CTPLManager::GetInstance().LoadTPL();
	//CMessageHandle::GetInstance();
	CDirtyWord::GetInstance().OI_Dirty_start();
	CLoginObjManager::GetInstance().Initialize();
	CLoginQueueMgr::GetInstance();
	return 0;
}

int32_t LoginServer::Finalize()
{
	CLoginObjManager::GetInstance().Finalize();
	CLoginObjManager::ReleaseInstance();
	GameHostManager::ReleaseInstance();
	CProxyClientService::ReleaseInstance();
	CTPLManager::ReleaseInstance();
	//CMessageHandle::ReleaseInstance();
	CDirtyWord::ReleaseInstance();
	CLoginQueueMgr::ReleaseInstance();
	return 0;
}

int32_t LoginServer::client_msg_dispatch(std::string& msg, unsigned long uid, uint32_t msgId)
{
//	return server_net.client_msg_dispatch(msg, uid, msgId);

	CLoginChannel* channel = login_server_.GetChannel(uid);
	if (channel == NULL )
	{
		LOG_ERROR("default", "channel is null!");
		login_server_.CloseChannel(uid);
		return -1;
	}
	const char* msg_body = msg.c_str();
	::common::CNetMsgTransfer::out_tcp_for_client(*channel, uid, msgId, msg_body, msg.size());
	return ::common::SUCCEED;
}

// int32_t LoginServer::AddClientMsg(uint32_t socketId, uint32_t msgId, std::string &msg)
// {
// 	CClientSocketMsg client_msg;
// 	client_msg.SetMsg(msg, socketId, msgId);
// 	CMessageHandle::GetInstance().AddClientMsgPtr(client_msg);
// 	return 0;
// }
// 
// int32_t LoginServer::AddServerMsg(uint32_t msgId, std::string &msg, const common::CProxyHead& head)
// {
// 	CProxySocketMsg server_msg;
// 	server_msg.SetMsg(head, msg, 0);
// 	CMessageHandle::GetInstance().AddServerMsgPtr(server_msg);
// 	return 0;
// }

void LoginServer::client_close_socket(uint32_t uid)
{
	LOG_ERROR("default","close client socket[%u]", uid);
	//server_net.close_client(uid);
	login_server_.CloseChannel(uid);
}

bool LoginServer::is_connnected(uint32_t uid)
{
	return server_net.is_connnected(uid);
}

void LoginServer::del_client_socket(uint32_t fd)
{
	CLoginLogic::GetInstance().DespawnClient(fd);
	CLoginQueueMgr::GetInstance().RemoveFromLoginQueue(fd);
}

void LoginServer::ProcessClientMsg(CClientSocketMsg& val)
{
	LOG_DEBUG("default"," process socket msg %d processed Begin =====", val.m_protocol_number);


	CJsonMessageBase msg;
	bool ret = msg.ParseAcceptJson(val.msg_);
	if (ret == false)
	{
		LOG_ERROR("default","msg parse err!  msgid[%d][%s]", val.m_protocol_number, val.msg_.c_str());
		return;
	}
	msg.set_from_socket_id(val.fd_);

	LoginPlayerMsgProcess process = LoginServer::GetInstance().GetPlayerMsgFactory().GetMsgProcess(val.m_protocol_number);
	if (process == NULL)
	{
		LOG_ERROR("default","process is null! msgid[%u]", val.m_protocol_number);
		return;
	}

	process(msg);

	LOG_DEBUG("default"," process socket msg %d processed OK =====", val.m_protocol_number);
}

void LoginServer::TickUpdate()
{
	CLoginQueueMgr::GetInstance().TickUpdate();
}

int32_t LoginServer::ServerStart()
{
	CProxyClientService::GetInstance().CheckConnect();
	CProxyClientService::GetInstance().EnableReconnect(2000);
	return 0;
}

int main(int argc, char* argv[])
{
#ifdef _MSC_VER
	SetCtrlCHandle(true);
#endif
	int retcode = LoginServer::GetInstance().ServiceMain(argc, argv);
	LoginServer::ReleaseInstance();
#ifdef _MSC_VER
	SetCtrlCHandle(false);
#endif
	return retcode;
}

void CLoginChannel::OnMsgEvent()
{
	while (true)
	{

		uint32_t msg_id = 0;

		std::string content;

		bool ret_trans = ::common::CNetMsgTransfer::in_tcp_for_client(*this, content, msg_id);

		if (ret_trans == false) {
			return;
		}
		CJsonMessageBase msg;
		bool ret = msg.ParseAcceptJson(content);
		if (ret == false)
		{
			LOG_ERROR("default", "msg parse err!  msgid[%d][%s]", msg_id, content.c_str());
			return;
		}
		msg.set_from_socket_id(fd());
		LoginPlayerMsgProcess process = LoginServer::GetInstance().GetPlayerMsgFactory().GetMsgProcess(msg_id);
		if (process == NULL)
		{
			LOG_ERROR("default", "process is null! msgid[%u]", msg_id);
			return;
		}

		process(msg);

		
	}
}

void CLoginChannel::OnConnect()
{
	LOG_ERROR("default", "on connect");
}

void CLoginChannel::OnDisconnect()
{
	LOG_ERROR("default", "on disconnect");
	LoginServer::GetInstance().del_client_socket(fd());
}
